﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Collections.Generic;
using LiveLinq;
using NUnit.Framework;

namespace LiveLinqTests
{
	[TestFixture]
	public class Cast : AssertionHelper
	{
		readonly List<NotifyCollectionChangedEventArgs> _list = new List<NotifyCollectionChangedEventArgs>();

		[Test]
		public void CastSimpleScenario()
		{
			var source = new ObservableCollection<double> { 5.3 };

			var actual = ObservableEnumerable.Cast<int>(source);
			var nc = actual as INotifyCollectionChanged;
			nc.CollectionChanged += (sender, e) => _list.Add(e);

			Expect(source.Count, EqualTo(1));
			Expect(actual.Count(), EqualTo(source.Count));
			//Expect(actual.First(), EqualTo(source.First()));

			CollectionAssert.AreEqual(source, actual);

			source.Add(10);

			CollectionAssert.AreEqual(source, actual);

			Expect(_list.Count, EqualTo(1));
			//Expect(_list.First().Action == NotifyCollectionChangedAction.Add);
			//Expect(_list.First().NewItems[0], EqualTo(source[1]));

			var itemToRemove = source[1];
			source.Remove(itemToRemove);

			CollectionAssert.AreEqual(source, actual);
			Expect(_list.Count, EqualTo(2));
			Expect(_list[1].Action == NotifyCollectionChangedAction.Remove);
			Expect(_list[1].OldItems[0], EqualTo(itemToRemove));
		}

		[Test]
		public void SafeDownCastSimpleScenario()
		{
			var source = new ObservableCollection<Item> { new Item(5) };

			var actual = ObservableEnumerable.Cast<IItem, Item>(source);
			var nc = actual as INotifyCollectionChanged;
			nc.CollectionChanged += (sender, e) => _list.Add(e);

			Expect(source.Count, EqualTo(1));
			Expect(actual.Count(), EqualTo(source.Count));
			//Expect(actual.First(), EqualTo(source.First()));

			CollectionAssert.AreEqual(source, actual);

			source.Add(new Item(10));

			CollectionAssert.AreEqual(source, actual);

			Expect(_list.Count, EqualTo(1));
			//Expect(_list.First().Action == NotifyCollectionChangedAction.Add);
			//Expect(_list.First().NewItems[0] == source[1]);

			var itemToRemove = source[1];
			source.Remove(itemToRemove);

			CollectionAssert.AreEqual(source, actual);
			Expect(_list.Count, EqualTo(2));
			Expect(_list[1].Action == NotifyCollectionChangedAction.Remove);
			Expect(_list[1].OldItems[0] == itemToRemove);
		}
	}
}